/*
  	usteve
	
	camera

  	FILE NAME:
  
  		cameradriver.cpp
  
  	DESCRIPTION:

		A driver program for our camera class

  	MODIFICATION HISTORY:
  
  		20-DEC-2008	Phillip Napieralski
*/

#include "camera.h"

int g_screenWidth = 800;
int g_screenHeight = 600;

Camera camera;

/* Draw a simple grid defining our boundaries */
void DrawOOBGrid3D( int size )
{
		Point3 start(-size,-size,-size);
		const float SPACING = 2.5f;

		glPushMatrix();
		glColor3ub(0,255,0);
		glTranslatef( 0,0, size-1.0f );	
		for( int k = 0; k < 4; k++)
		{
			glRotatef( 90*k, 1, 0, 0 );
			glBegin( GL_LINES );
				for( int i = 0; i <= 2*size; i+= SPACING )
				{
					glVertex3f( start.x + i, start.y + 2*size, start.z ); /* xz plane */
					glVertex3f( start.x + i, start.y, start.z );
					glVertex3f( start.x + 2*size, start.y + i, start.z);
					glVertex3f( start.x, start.y + i, start.z);
				}
			glEnd();
		}

		glBegin( GL_LINES );
			for( int i = 0; i <= 2*size; i+= SPACING )
			{
					glVertex3f( start.x , start.y + 2*size, start.z + i );
					glVertex3f( start.x, start.y, start.z + i );
					glVertex3f( start.x , start.y + i, start.z + 2*size );
					glVertex3f( start.x, start.y + i, start.z );

					glVertex3f( start.x+2*size, start.y + 2*size, start.z + i );
					glVertex3f( start.x+2*size, start.y, start.z + i );
					glVertex3f( start.x+2*size, start.y + i, start.z + 2*size );
					glVertex3f( start.x+2*size, start.y + i, start.z );
			}
		glEnd();
		glPopMatrix();
}


void Init()
{
	glEnable( GL_DEPTH_TEST );
	camera.setDefault();
	camera.applyShape();

}
void Display()
{
	glClearColor(0,0,0,0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	camera.applyShape();
	camera.look();
	/* Draw everything here */
	DrawOOBGrid3D( 5.0f );
	
	glutSwapBuffers();
}	

void Idle()
{
	glutSetCursor( GLUT_CURSOR_CROSSHAIR );

	/* update stuff here */

	glutPostRedisplay();
}

/* This nifty piece of code moves the camera based on mouse movement */
static bool warped = false;
void PassiveMotion( int x, int y )
{
	if( !warped )
	{
		int gW = g_screenWidth >> 1;
		int gH = g_screenHeight >> 1;
		int deltaX = x - gW;
		int deltaY = y - gH;

		/* rotate here */
		camera.yaw( (float)deltaX / 1000.0f );
		camera.lookUp( (float)deltaY / 1000.0f );

		warped = true;
		glutWarpPointer( gW, gH );
	}
	else
		warped = false;

	glutPostRedisplay();
}

void Keyboard( unsigned char key, int x, int y )
{
	switch( tolower(key) )
	{
	case 27:
		exit(0);
		break;

	case 'w':
		camera.moveForward( 0.1f );
		break;

	case 's':
		camera.moveForward( -0.1f );
		break;

	case 'a':
		camera.moveRight( -0.1f );
		break;

	case 'd':
		camera.moveRight( 0.1f );
		break;
	default:break;
	}

	glutPostRedisplay();
}

void Special(int key, int x, int y)
{
	switch( key )
	{
	case GLUT_KEY_UP:
		break;
	default: break;
	}
	glutPostRedisplay();
}

void Reshape( int width, int height )
{
	g_screenWidth = width;
	g_screenHeight = height;
	glViewport( 0,0, g_screenWidth, g_screenHeight );
	glutPostRedisplay();
}


void main(int argc, char **argv)
{
	char *windowName = "Camera Driver!";

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize( g_screenWidth, g_screenHeight);
	glutInitWindowPosition (100,100);
	
	glutCreateWindow(windowName);
	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutIdleFunc(Idle);
	glutSpecialFunc(Special);
	glutKeyboardFunc(Keyboard);
	glutPassiveMotionFunc(PassiveMotion);
	glutMotionFunc(PassiveMotion);
	
	Init();
	glutMainLoop();
}
